﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Management;
using System.Collections;
// namespaces necesarios para conexión a bd
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Data.SqlTypes;



using System.ComponentModel;
using System.Windows.Forms;
using System.Drawing;


namespace Persistencia_y_capa_de_negocio
{
    public class CADEdificio
    {
        private static readonly CADEdificio instancia = new CADEdificio();
        public static CADEdificio Instancia
        {
            get { return instancia; }
        }

        private string cadCon;  // Cadena de conexión conseguida desde app.config
        private SqlDataAdapter da;
        private SqlConnection c;
        private DataSet vdb;

        public CADEdificio()
        {
            try
            {
                cadCon = ConfigurationManager.ConnectionStrings["conexion"].ConnectionString;
                
                vdb = new DataSet();
                c = new SqlConnection(cadCon);
                da = new SqlDataAdapter("Select * from edificios", c);

                /*da = new SqlDataAdapter("SELECT * FROM (" +
                                          "SELECT *, ROW_NUMBER() OVER (ORDER BY nombre asc) " +
                                          "as fila FROM edificios) " +
                                          "as alias WHERE fila >= 0 and fila <= 5" , c);*/

               

                da.Fill(vdb, "Edificio");    // Ahora tenemos todo el contenido de edificios en local.
                //MessageBox.Show("lol");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

           
        }

        /// <summary>
        /// Insertamos en la base de datos el edificio, sin embargo
        /// sic ya existe, se modificará su contenido.
        /// </summary>
        /// <param name="ed">Variable con los datos necesarios que contiene un edificio.</param>
        public bool InsertarEdificio(ENEdificio ed)
        {
            DataTable t = new DataTable();

            t = vdb.Tables["Edificio"];
            // Ahora tengo la tabla edificio.
            DataRow r = null;

            bool insertado = false;

            string select = "nombre = \'" + ed.Nombre + "\'";
           

            try
            {
                // Si no lanza la excepción significa que hay que modificar.
                r = t.Select(select)[0];

                r["nombre"] = ed.Nombre;
                r["tipo"] = ed.Tipo.ToString();
                r["descripcion"] = ed.Descripcion;
                r["ataque"] = ed.Ataque;
                r["defensa"] = ed.Defensa;
                r["vida"] = ed.Vida;
                r["tiempo"] = ed.Tiempo;
                r["multiplicador"] = ed.Multiplicador;
                r["admin"] = ed.Admin;

                SqlCommandBuilder command = new SqlCommandBuilder(da);

                // Actualizamos los cambios en la BD real.
                da.Update(vdb, "Edificio");
                
                
            }
            catch (Exception)
            {
                // Significa que el resultado ha sido null. O sea que hay que insertar, no modificar.
                r = t.NewRow();

                r["nombre"] = ed.Nombre;
                r["tipo"] = ed.Tipo.ToString();
                r["descripcion"] = ed.Descripcion;
                r["ataque"] = ed.Ataque;
                r["defensa"] = ed.Defensa;
                r["vida"] = ed.Vida;
                r["tiempo"] = ed.Tiempo;
                r["multiplicador"] = ed.Multiplicador;
                r["admin"] = ed.Admin;

                // Añadimos la nueva fila a la tabla virtual.
                t.Rows.Add(r);

                SqlCommandBuilder command = new SqlCommandBuilder(da);

                // Actualizamos los cambios en la BD real.
                da.Update(vdb, "Edificio");

                insertado = true;
            }

            return insertado;
        }

        /// <summary>
        /// Recoje de la base de datos la tabla edificios y nos la muestra.
        /// </summary>
        /// <returns> Devuelve un ArrayList con los datos de todos los edificios.</returns>
        public ArrayList getEdificios()
        {
            ArrayList lista = new ArrayList();

            DataTable t = new DataTable();
            t = vdb.Tables["Edificio"];

            t.Clear();

            // Ahora toca modificar la vdb con los datos de la página actual.

            /*da = new SqlDataAdapter("SELECT * FROM (" +
                                      "SELECT *, ROW_NUMBER() OVER (ORDER BY nombre asc) " +
                                      "as fila FROM edificios) " +
                                      "as alias WHERE fila >= " + inicio.ToString() + "and fila <= " + final.ToString(), c);*/
            try
            {
                da = new SqlDataAdapter("select * from edificios", c);



                da.Fill(vdb, "Edificio");    // Ahora tenemos todo el contenido de edificios en local.

                t = vdb.Tables["Edificio"];

                foreach (DataRow r in t.Rows)
                {
                    ENEdificio ed = new ENEdificio();

                    // Insertamos los datos en el nuevo edificio.
                    ed.Id = Convert.ToInt32(r["id"]);
                    ed.Nombre = r["nombre"].ToString().Trim();
                    ed.Tipo = Convert.ToInt32(r["tipo"]);
                    ed.Descripcion = r["descripcion"].ToString().Trim();
                    ed.Ataque = Convert.ToInt32(r["ataque"]);
                    ed.Defensa = Convert.ToInt32(r["defensa"]);
                    ed.Vida = Convert.ToInt32(r["vida"]);
                    ed.Tiempo = Convert.ToInt32(r["tiempo"]);
                    ed.Admin = r["admin"].ToString().Trim();
                    lista.Add(ed);
                }
            }
            catch
            {

            }
            

            return lista;
        }

        /// <summary>
        /// Devuelve un ENEdificio a partir del nombre
        /// </summary>
        /// <param name="nombre"></param>
        /// <returns></returns>
        public ENEdificio getEdificio(string nombre)
        {
            ENEdificio ed = new ENEdificio();

            DataTable t = new DataTable();
            DataRow r = null;

            t = vdb.Tables["Edificio"];
            string select = "nombre = \'" + nombre + "\'";
            try
            {
                r = t.Select(select)[0];
            }
            catch (Exception)
            {
                return null;
            }
            ed.Id = Convert.ToInt32(r["id"]);
            ed.Nombre = r["nombre"].ToString().Trim();
            ed.Tipo = Convert.ToInt32(r["tipo"]);
            ed.Descripcion = r["descripcion"].ToString().Trim();
            ed.Ataque = Convert.ToInt32(r["ataque"]);
            ed.Defensa = Convert.ToInt32(r["defensa"]);
            ed.Vida = Convert.ToInt32(r["vida"]);
            ed.Tiempo = Convert.ToInt32(r["tiempo"]);
            ed.Admin = r["admin"].ToString().Trim();

            ed.Unidades = CADUnidad.Instancia.getUnidadesEdificio(ed.Id);
            ed.RecursosCreables = CADRecurso.Instancia.getRecursosEdificio(ed.Id);
            ed.Costes = CADRecurso.Instancia.getCostesEdificio(ed.Id);

            return ed;
        }

        /// <summary>
        /// Devuelve un ENEdificio a partir del ID
        /// </summary>
        /// <param name="nombre"></param>
        /// <returns></returns>
        public ENEdificio getEdificioporID(int id)
        {
            ENEdificio ed = new ENEdificio();

            DataTable t = new DataTable();
            DataRow r = null;

            t = vdb.Tables["Edificio"];
            string select = "id = \'" + id + "\'";
            try
            {
                r = t.Select(select)[0];
            }
            catch (Exception)
            {
                return null;
            }
            ed.Id = Convert.ToInt32(r["id"]);
            ed.Nombre = r["nombre"].ToString().Trim();
            ed.Tipo = Convert.ToInt32(r["tipo"]);
            ed.Descripcion = r["descripcion"].ToString().Trim();
            ed.Ataque = Convert.ToInt32(r["ataque"]);
            ed.Defensa = Convert.ToInt32(r["defensa"]);
            ed.Vida = Convert.ToInt32(r["vida"]);
            ed.Tiempo = Convert.ToInt32(r["tiempo"]);
            ed.Admin = r["admin"].ToString().Trim();

            ed.Unidades = CADUnidad.Instancia.getUnidadesEdificio(ed.Id);
            ed.RecursosCreables = CADRecurso.Instancia.getRecursosEdificio(ed.Id);
            ed.Costes = CADRecurso.Instancia.getCostesEdificio(ed.Id);

            return ed;
        }
        /// <summary>
        /// Devuelve el número de edificios que han sido creados por el administrador que recibe por parámetro.
        /// </summary>
        /// <param name="nombre">Nombre del administrador.</param>
        /// <returns>Devuelve un entero con la cantidad de edificios que han sido creados por el administrador.</returns>
        public int getNumEdificiosPorAdmin(string nombre)
        {
            // Obtenemos la tabla edificios.
            DataTable t = new DataTable();
            t = vdb.Tables["Edificio"];

            try
            {
                // Devolvemos la cantidad de edificios con ese creador.
                return t.Select("admin = \'" + nombre + "\'").Count();

            }
            catch (Exception)
            {
                return 0;
            }
        }

        /// <summary>
        /// Borra el edificio seleccionado de la base de datos.
        /// </summary>
        /// <param name="nombre">Nombre del edificio que queremos borrar.</param>
        public void EliminaEdificio(string nombre)
        {
            string select = "nombre = \'" + nombre + "\'";

            DataTable t = vdb.Tables["Edificio"];
            
            try
            {
                DataRow r = t.Select(select)[0];
                r.Delete();

                SqlCommandBuilder command = new SqlCommandBuilder(da);

                // Actualizamos los cambios en la BD real.
                da.Update(vdb, "Edificio");
            }
            catch
            {
                // Soltamos algún errorcete.

                MessageBox.Show(nombre);
            }
        }

        public int getNumEdificios()
        {
            DataTable t = new DataTable();
            t = vdb.Tables["Edificio"];
            return t.Rows.Count;
        }

        /// <summary>
        /// Devuelve un arrayList de edificios que concuerden con los filtros de búsqueda
        /// </summary>
        /// <param name="nombre"></param>
        /// <param name="tipo"></param>
        /// <param name="defensa"></param>
        /// <param name="ataque"></param>
        /// <param name="coste"></param>
        /// <returns></returns>
        public ArrayList getEdificiosBuscar(string nombre, int tipo, string defensa, string ataque, ArrayList coste)
        {
            DataTable t = vdb.Tables["Edificio"];
            string select = "";
            ArrayList lista = new ArrayList();

            if (nombre != "")
            {
                select += "nombre like \'%" + nombre + "%\' ";
            }
            if (tipo != -1)
            {
                if (nombre != "")
                {
                    select += " and ";
                }
                select += "tipo = " + tipo + " ";
            }
            if (defensa != "")
            {
                if (nombre != "" || tipo != -1)
                {
                    select += " and ";
                }
                select += "defensa = " + defensa + " ";
            }
            if (ataque != "")
            {
                if (nombre != "" || tipo != -1 || defensa != "")
                {
                    select += " and ";
                }
                select += "ataque = " + ataque + " ";
            }

            foreach (DataRow r in t.Select(select))
            {
                ENEdificio ed = CADEdificio.instancia.getEdificio(r["nombre"].ToString());

                lista.Add(ed);
            }

            return lista;
        }

        public ArrayList getEdificiosTipo(int tipo)
        {
            DataTable t = vdb.Tables["Edificio"];
            ArrayList lista = new ArrayList();
            string select = "tipo = " + tipo;

            foreach (DataRow r in t.Select(select))
            {
                ENEdificio ed = CADEdificio.instancia.getEdificio(r["nombre"].ToString());
                lista.Add(ed);
            }

            return lista;
        }

    }
}
